/** 
 * File: AchievementDetailsController.java
 * @author: Adam Phung
 * Date Created:
 * Date Modified: Nov 26, 2012 
 * Description: Used for either adding new Achievement or editing an existing one
 */
package edu.bu.cs673.superkids123.parents.controller;

import java.util.HashSet;
import java.util.Set;

import javax.swing.JOptionPane;

import edu.bu.cs673.superkids123.AbstractController;
import edu.bu.cs673.superkids123.AbstractFrame;
import edu.bu.cs673.superkids123.common.model.Achievement;
import edu.bu.cs673.superkids123.common.model.AchievementRule;
import edu.bu.cs673.superkids123.parents.DataObjectAccess.AchievementManager;
import edu.bu.cs673.superkids123.parents.view.AchievementDetailsView;
import edu.bu.cs673.superkids123.parents.view.ManageAchievementsView;
import edu.bu.cs673.superkids123.parents.view.dialog.AchievementRuleDialog;

/**
 * The Class AchievementDetailsController.
 */
public class AchievementDetailsController extends AbstractController {

	/** Selected Achievement used for editing an existing Achievement only.
	 *  Stays null if creating a new achievement. */
	public static Achievement selectedAchievement = null;
	
	/**
	 * Instantiates a new achievement details controller.
	 *
	 * @param mainFrame the main frame
	 */
	public AchievementDetailsController(AbstractFrame mainFrame) {
		super(mainFrame);
	}
	
	/**
	 * Adds the achievement.
	 */
	public void addAchievement() {
		selectedAchievement = null;
		getMainFrame().changeView(AchievementDetailsView.class);
	}

	/**
	 * Edits the achievement.
	 *
	 * @param achievement the achievement
	 */
	public void editAchievement(Achievement achievement) {
		selectedAchievement = achievement;
		getMainFrame().changeView(AchievementDetailsView.class);
	}
	
	/**
	 * Adds the rule.
	 *
	 * @return the achievement rule
	 */
	public AchievementRule addRule() {
		AchievementRuleDialog d = new AchievementRuleDialog(null, true, null);
		d.setVisible(true);
		
		return d.getRule();
	}
	
	/**
	 * Edits the rule.
	 *
	 * @param rule the rule
	 * @return the achievement rule
	 */
	public AchievementRule editRule(AchievementRule rule) {
		AchievementRuleDialog d = new AchievementRuleDialog(null, true, rule);
		d.setVisible(true);
		
		return d.getRule();
	}
	
	/**
	 * Save achievement.
	 * 
	 * Depending on the status of selectedAchievement will either create new 
	 * or save existing Achievement.
	 *
	 * @param achievement The achievement data to save
	 */
	public void saveAchievement(Achievement achievement) {
		if (selectedAchievement == null) { // Add Achievement
			int result = AchievementManager.addAchievement(achievement);
			if (result == -1) {
				JOptionPane.showMessageDialog(null, "Error: Unable to save achievement.",
						"Database Error!", JOptionPane.ERROR_MESSAGE);
				return; // Error: stay on this page
			} else {
				JOptionPane.showMessageDialog(null, "Achievement Saved.",
						"Achievement Manager", JOptionPane.INFORMATION_MESSAGE);
			}
		} else { // Edit Achievement
			updateSelectedAchievement(achievement);
			boolean result = AchievementManager.updateAchievement(selectedAchievement);
			
			if (result) {
				JOptionPane.showMessageDialog(null, "Achievement Saved.",
						"Achievement Manager", JOptionPane.INFORMATION_MESSAGE);
			} else {
				JOptionPane.showMessageDialog(null, "Error: Unable to save achievement.",
						"Database Error!", JOptionPane.ERROR_MESSAGE);
				return; // Error: stay on this page
			}
		}
		getMainFrame().changeView(ManageAchievementsView.class);
	}

	/**
	 * Gets the selected achievement.
	 *
	 * @return the selected achievement
	 */
	public static Achievement getSelectedAchievement() {
		return selectedAchievement;
	}

	/**
	 * Sets the selected achievement.
	 *
	 * @param current the new selected achievement
	 */
	public static void setSelectedAchievement(Achievement current) {
		selectedAchievement = current;
	}
	
	/**
	 * Update selectedAchievement with the data from the form.
	 * selectedAchievement contains the needed unique id of the Achievement
	 *
	 * @param achievement The modified data to update selectedAchievement with.
	 */
	private void updateSelectedAchievement(Achievement achievement) {
		selectedAchievement.setName(achievement.getName());
		selectedAchievement.setDescription(achievement.getDescription());
		selectedAchievement.setPrize(achievement.getPrize());
		selectedAchievement.setPoints(achievement.getPoints());
		
		Set<AchievementRule> rules = new HashSet<AchievementRule>();
		
		for (AchievementRule rule : achievement.getRules()) {
			rule.setAchievement(selectedAchievement);
			rules.add(rule);
		}
		
		selectedAchievement.setRules(rules);
	}
}
